﻿using UnityEngine;
using UnityEngine.EventSystems;

namespace ZyGame.Game
{
    /// <summary>
    /// 相机跟随组件
    /// </summary>
    public class LookAtEntityComponent : EntityComponent
    {
        private Vector3 orgins;
        private float distance, radian;
        private bool isRotation = true;
        private bool isCheckRotation = true;
        public Vector3 offset { get; set; }
        public Camera camera { get; private set; }
        public TransformComponent transformComponent { get; private set; }
        private Vector3 screne = new Vector3(Screen.width / 2, Screen.height);


        public override void Awake(params object[] dataList)
        {
            base.Awake(dataList);
            this.camera = dataList.GetAndCast<Camera>(0);
            if (camera is null)
            {
                return;
            }

            Vector3 position = dataList.CastOrDefault(1, new Vector3(2, 2.2f, -1));
            Vector3 rotation = dataList.CastOrDefault(2, new Vector3(12, 0, 0));
            this.isRotation = dataList.CastOrDefault<bool>(3, true);
            transformComponent = this.entity.GetComponent<TransformComponent>();
            if (transformComponent is null)
            {
                Client.Console.WriteLine($"the entity is not find {nameof(TransformComponent)}");
                return;
            }

            // orgins = transformComponent.position;
            // camera.transform.position = position;
            camera.transform.position = new Vector3(transformComponent.position.x, 2f, transformComponent.position.z - 4);
            camera.transform.LookAt(transformComponent.position); // = Quaternion.Euler(rotation);
            offset = camera.transform.position - transformComponent.position;
            distance = Vector3.Distance(camera.transform.position, transformComponent.position);
            radian = -(Vector3.Angle(Vector3.up, Vector3.back) * Mathf.Deg2Rad);
            Client.Tools.LateUpdate(Execute);
        }

        protected virtual void Execute()
        {
            EnsureRotationCamera();
            EnsureFollowEntity();
        }

        private void EnsureFollowEntity()
        {
            if (transformComponent is null || camera is null)
            {
                return;
            }

            // Vector3 m = transformComponent.position - orgins;
            // camera.transform.TransformPoint(m);
            camera.transform.position = transformComponent.position + offset;
        }

        private void EnsureRotationCamera()
        {
            if (isRotation is false)
            {
                return;
            }

            if (Input.GetMouseButtonDown(0))
            {
                if (EventSystem.current.IsPointerOverGameObject())
                {
                    isCheckRotation = false;
                    return;
                }

                isCheckRotation = true;
            }

            if (Input.GetMouseButtonUp(0))
            {
                isCheckRotation = true;
                orgins = Vector3.zero;
            }

            if (Input.GetMouseButton(0) is false || isCheckRotation is false || transformComponent is null || camera is null)
            {
                return;
            }

            if (Input.mousePosition.x < screne.x)
            {
                return;
            }

            if (orgins == Vector3.zero)
            {
                orgins = Input.mousePosition;
                return;
            }

            if (orgins == Input.mousePosition)
            {
                return;
            }

            float allRate = (Input.mousePosition.x - screne.x) / screne.x;
            float segment = allRate - (orgins.x - screne.x) / screne.x;
            float angle = 360f * segment;
            Vector3 vector3 = Quaternion.AngleAxis(angle, transformComponent.transform.up) * (offset);
            vector3 = transformComponent.position + vector3;
            camera.transform.position = new Vector3(vector3.x, camera.transform.position.y, vector3.z);
            camera.transform.rotation = Quaternion.Euler(new Vector3(12, camera.transform.rotation.eulerAngles.y + angle, 0));
            offset = camera.transform.position - transformComponent.position;
            orgins = Input.mousePosition;
        }

        public override void Dispose()
        {
            base.Dispose();
            Client.Tools.RemoveCallback(Execute);
        }
    }
}